﻿#--------------------------------------------
# Declare Global Variables and Functions here
#--------------------------------------------

#region Main Form Global Variables

#RichTextBox Font Defaults
$Global:fontBold = new-object System.Drawing.Font("Calibri",8,[Drawing.FontStyle]'Bold' )
$Global:fontHeader = new-object System.Drawing.Font("Calibri Light",10,[Drawing.FontStyle]'Bold' )
$Global:fontNormal = new-object System.Drawing.Font("Calibri",8,[Drawing.FontStyle]'Regular')
$Global:fontSmall = new-object System.Drawing.Font("Calibri Light",7,[Drawing.FontStyle]'Regular')
$Global:fontItalic = new-object System.Drawing.Font("Calibri Light",8,[Drawing.FontStyle]'Italic')
$Global:fontCode = new-object System.Drawing.Font("Lucida Console",8,[Drawing.FontStyle]'Bold')

$ADServer = Read-Host -Prompt "Please enter your AD server"
$ExchServer = Read-Host -Prompt "Please enter your Exchange server"
$LyncServer = Read-Host -Prompt "Please enter your Lync server"

$Global:PSAD = $ADServer
$Global:PSExchServer = $ExchServer
$Global:PSLync = $LyncServer
#endregion Main Form Global Variables

#region Global Functions
function Get-ScriptDirectory{ 
	if($hostinvocation -ne $null)
	{
		Split-Path $hostinvocation.MyCommand.path
	}
	else
	{
		Split-Path $script:MyInvocation.MyCommand.Path
	}
}
#function OnApplicationExit{
#	
#}
function ITMTAppend-RTB{
	Param(
		[System.Windows.Forms.RichTextBox]$RichTextBox,
		[System.Drawing.Font]$Font,
		[string]$Text,
		[switch]$Clear,
		[switch]$NewLine,
		[string]$Color
		
	)
	
	if($Clear)
	{
		$RichTextBox.Items.Clear();
	}
	
	elseif($NewLine){
		$RichTextBox.AppendText([char]10)	
	}
	elseif($Color){
		$RichTextBox.SelectionFont = $Font
		$RichTextBox.SelectionColor = $Color
		$RichTextBox.AppendText($Text)
	}
	else{
		$RichTextBox.SelectionFont = $Font
		$RichTextBox.SelectionColor = 'Black'
		$RichTextBox.AppendText($Text)
	}
}
function Compare-Hashtable([Hashtable]$ReferenceObject,[Hashtable]$DifferenceObject,[switch]$IncludeEqual){
  # Creates a result object.
  function result( [string]$side ) {
    New-Object PSObject -Property @{
      'InputPath'= "$path$key";
      'SideIndicator' = $side;
      'ReferenceValue' = $refValue;
      'DifferenceValue' = $difValue;
    }
  }

  # Recursively compares two hashtables.
  function core( [string]$path, [Hashtable]$ref, [Hashtable]$dif ) {
    # Hold on to keys from the other object that are not in the reference.
    $nonrefKeys = New-Object 'System.Collections.Generic.HashSet[string]'
    $dif.Keys | foreach { [void]$nonrefKeys.Add( $_ ) }

    # Test each key in the reference with that in the other object.
    foreach( $key in $ref.Keys ) {
      [void]$nonrefKeys.Remove( $key )
      $refValue = $ref.$key
      $difValue = $dif.$key

      if( -not $dif.ContainsKey( $key ) ) {
        result '<='
      }
      elseif( $refValue -is [hashtable] -and $difValue -is [hashtable] ) {
        core "$path$key." $refValue $difValue
      }
      elseif( $refValue -ne $difValue ) {
        result '<>'
      }
      elseif( $IncludeEqual ) {
        result '=='
      }
    }

    # Show all keys in the other object not in the reference.
    $refValue = $null
    foreach( $key in $nonrefKeys ) {
      $difValue = $dif.$key
      result '=>'
    }
  }

  core '' $ReferenceObject $DifferenceObject
}
#endregion Global Functions

#region Remoting Engine
# Todo: Set the ability to fire off and keep track of individual remoting sessions.
function ITMTInvoke-AD{
	
}

function ITMTInvoke-Exchange{
	
}

function ITMTInvoke-Lync{
	
}

function ITMTCreate-RemoteSession{
<#
	.SYNOPSIS
		Initialize Remote Powershell Session

	.DESCRIPTION
		Creates remote sessions to management servers

	.PARAMETER AD
		Creates an AD remote session
	
	.PARAMETER Exchange
		Creates an Exchange remote session
	
	.PARAMETER Lync
		Creates a Lync remote session
	
	.PARAMETER ALL
		Creates all available remote sessions
	
	.EXAMPLE
		ITMTCreate-RemoteSession 
#>
	Param(
		[switch]$AD,
		[switch]$Exchange,
		[switch]$Lync,
		[switch]$All
	)
	
	if($AD){
		$Global:sAD = $(try {New-PSSession -ComputerName $Global:PSAD -Name 'PSRAD' -Authentication 'Credssp' -Credential $Global:c -ea 'Stop'}
		catch [Exception]{
			$string = ($_.Exception.Message+"`n`nMost likely however, you just entered the wrong username and password.")
			[System.Windows.Forms.MessageBox]::Show($string)
			return
		})
		Invoke-Command { Import-Module ActiveDirectory } -Session $Global:sAD
		Write-Host "Created AD Session: $Global:sAD"
	}
	if($Exchange){
		try{$Global:sExch = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $global:PSExchServer -Authentication Kerberos -Name 'PSRExchange'}
		catch [Exception]{
			[System.Windows.Forms.MessageBox]::Show($_.Exception.Message)
			Write-Host "Entered Exchange? WTF?"
			ITMTRemove-RemoteSession -All
			return
		}
		Write-Host "Created Exchange Session: $Global:sExch"
	}
	if($Lync){
		try{$Global:sLync = New-PSSession -ConnectionUri $Global:PSLync -Name 'PSRLync' -Authentication 'NegotiateWithImplicitCredential'}
		catch [Exception]{
			[System.Windows.Forms.MessageBox]::Show($_.Exception.Message)
			ITMTRemove-RemoteSession -All
			return
		}
		Write-Host "Created Lync Session: $Global:sLync"
	}
	if($All -or (-not $AD -and -not $Exchange -and -not $Lync)){
		
		try{$Global:sAD = New-PSSession -ComputerName $Global:PSADServer -Name 'PSRAD'-Authentication 'Credssp' -Credential $Global:c}
		catch [Exception]{
			[System.Windows.Forms.MessageBox]::Show($_.Exception.Message)
			return
		}
		Invoke-Command { Import-Module ActiveDirectory } -Session $Global:sAD
		
		try{$Global:sExch = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $global:PSExchServer -Authentication Kerberos -Name 'PSRExchange'}
		catch [Exception]{
			[System.Windows.Forms.MessageBox]::Show($_.Exception.Message)
			ITMTRemove-RemoteSession -AD
			return
		}
		
		try{$Global:sLync = New-PSSession -ConnectionUri $Global:PSLync -Name 'PSRLync' -Authentication 'NegotiateWithImplicitCredential'}
		catch [Exception]{
			[System.Windows.Forms.MessageBox]::Show($_.Exception.Message)
			ITMTRemove-RemoteSession -AD -Exchange
			return
		}
		
		if($global:sExch -and $global:sAD -and $global:sLync){
			Write-Host "Created All Remote Sessions"
		}
	}
	
}

function ITMTCheck-RemoteSession{
<#
	.SYNOPSIS
		Checks current remote powershell sessions

	.DESCRIPTION
		Creates remote sessions to management servers

	.PARAMETER Exchange
		Checks for an Exchange remote session
	
	.PARAMETER Lync
		Checks for a Lync remote session
	
	.EXAMPLE
		ITMTCheck-RemoteSession 
#>
	Param(
		[switch]$AD,
		[switch]$Exchange,
		[switch]$Lync,
		[switch]$All
	)
}

function ITMTRemove-RemoteSession{
	Param(
		[switch]$AD,
		[switch]$Exchange,
		[switch]$Lync,
		[switch]$All
	)
	if($AD){
		Write-Host "AD Session Cleaned"
		Remove-PSSession $Global:sAD
	}
	if($Exchange){
		Write-Host "Exchange Session Cleaned"
		Remove-PSSession $Global:sExch
	}
	if($Lync){
		Write-Host "Lync Session Cleaned"
		Remove-PSSession $Global:sLync
	}
	if($All -or (-not $AD -and -not $Exchange -and -not $Lync)){
		try{Remove-PSSession $Global:sAD}
		catch [Exception]{
			[System.Windows.Forms.MessageBox]::Show($_.Exception.Message)
			return
		}
		try{Remove-PSSession $Global:sExch}
		catch [Exception]{
			[System.Windows.Forms.MessageBox]::Show($_.Exception.Message)
			return
		}
		try{Remove-PSSession $Global:sLync}
		catch [Exception]{
			[System.Windows.Forms.MessageBox]::Show($_.Exception.Message)
			return
		}
		Write-Host "ALL Sessions Cleaned"
	}
}

#endregion Remoting Engine

#Sample variable that provides the location of the script
[string]$ScriptDirectory = Get-ScriptDirectory



